home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / os2 / pmnos11s / kiss.c < prev    next >
C/C++ Source or Header  |  1993-07-30  |  5KB  |  214 lines

  1. /* Routines for AX.25 encapsulation in KISS TNC
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Modified by G1EMM 19/11/90 to support multi-port KISS mode. 
  5.  */
  6.  /* Mods by G1EMM */
  7.  
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "kiss.h"
  12. #include "devparam.h"
  13. #include "slip.h"
  14. #include "asy.h"
  15. #include "ax25.h"
  16. #include "pktdrvr.h"
  17.  
  18. /* Send raw data packet on KISS TNC */
  19. int
  20. kiss_raw(iface,data)
  21. struct iface *iface;
  22. struct mbuf *data;
  23. {
  24.     register struct mbuf *bp;
  25.  
  26.     /* Put type field for KISS TNC on front */
  27.     if((bp = pushdown(data,1)) == NULLBUF){
  28.         free_p(data);
  29.         return -1;
  30.     }
  31.     bp->data[0] = PARAM_DATA;
  32.     bp->data[0] |= (iface->port << 4);
  33.     if(iface->port){
  34.         iface->rawsndcnt++;
  35.         iface->lastsent = Clock;
  36.     }
  37.     /* slip_raw also increments sndrawcnt */
  38.     slip_raw(Slip[iface->xdev].iface,bp);
  39.     return 0;
  40. }
  41.  
  42. /* Process incoming KISS TNC frame */
  43. void
  44. kiss_recv(iface,bp)
  45. struct iface *iface;
  46. struct mbuf *bp;
  47. {
  48.     char kisstype;
  49.     struct iface *kissif;
  50.     int port;
  51.  
  52.     kisstype = PULLCHAR(&bp);
  53.     port = kisstype >> 4;
  54.  
  55.     if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF){
  56.         free_p(bp);
  57.         return;
  58.     }    
  59.  
  60.     switch(kisstype & 0xf){
  61.     case PARAM_DATA:
  62.         ax_recv(kissif,bp);
  63.         break;
  64.     default:
  65.         free_p(bp);
  66.         break;
  67.     }
  68. }
  69. /* Perform device control on KISS TNC by sending control messages */
  70. int32
  71. kiss_ioctl(iface,cmd,set,val)
  72. struct iface *iface;
  73. int cmd;
  74. int set;
  75. int32 val;
  76. {
  77.     struct mbuf *hbp;
  78.     char *cp;
  79.     int rval = 0;
  80.  
  81.     /* At present, only certain parameters are supported by
  82.      * stock KISS TNCs. As additional params are implemented,
  83.      * this will have to be edited
  84.      */
  85.     switch(cmd){
  86.         case PARAM_RETURN:
  87.         case PARAM_RETURN2:
  88.             set = 1;    /* Note fall-thru */
  89.         case PARAM_TXDELAY:
  90.         case PARAM_PERSIST:
  91.         case PARAM_SLOTTIME:
  92.         case PARAM_TXTAIL:
  93.         case PARAM_FULLDUP:
  94.         case PARAM_HW:
  95.             if(!set){
  96.                 rval = -1;    /* Can't read back */
  97.                 break;
  98.             }
  99.             /* Allocate space for cmd and arg */
  100.             if((hbp = alloc_mbuf(2)) == NULLBUF){
  101.                 free_p(hbp);
  102.                 rval = -1;
  103.                 break;
  104.             }
  105.             cp = hbp->data;
  106.             *cp++ = cmd;
  107.             *cp = val;
  108.             hbp->cnt = 2;
  109.             if(hbp->data[0] != (char) PARAM_RETURN)
  110.                 hbp->data[0] |= (iface->port << 4);
  111.             if(iface->port){
  112.                 iface->rawsndcnt++;
  113.                 iface->lastsent = Clock;
  114.             }
  115.             /* Even more "raw" than kiss_raw */
  116.             slip_raw(Slip[iface->xdev].iface,hbp);
  117.             /*        slip_raw(iface,hbp);    / * Even more "raw" than kiss_raw */
  118.             rval = val;
  119.             break;
  120.         case PARAM_SPEED:    /* These go to the local asy driver */
  121.         case PARAM_DTR:
  122.         case PARAM_RTS:
  123.         case PARAM_UP:
  124.         case PARAM_DOWN:
  125.             rval = asy_ioctl(iface,cmd,set,val);
  126.             break;
  127.         default:        /* Not implemented */
  128.             rval = -1;
  129.             break;
  130.         }
  131.     return rval;
  132. }
  133.  
  134. int
  135. kiss_stop(iface)
  136. struct iface *iface;
  137. {
  138.     Slip[iface->xdev].kiss[iface->port] = NULLIF;
  139.     return 0;
  140. }
  141.  
  142. /* Attach a kiss interface to an existing asy interface in the system
  143.  * argv[0]: hardware type, must be "kiss"
  144.  * argv[1]: master interface, e.g., "ax4"
  145.  * argv[2]: kiss port, e.g., "4"
  146.  * argv[3]: interface label, e.g., "ax0"
  147.  * argv[4]: maximum transmission unit, bytes
  148.  */
  149. int
  150. kiss_attach(argc,argv,p)
  151. int argc;
  152. char *argv[];
  153. void *p;
  154. {
  155.     struct iface *if_asy, *if_kiss;
  156.     int port;
  157.  
  158.     if((if_asy = if_lookup(argv[1])) == NULLIF){
  159.         tprintf("Interface %s does not exist\n",argv[1]);
  160.         return -1;
  161.     }
  162.  
  163.     /* Check for ASY type interface ! - WG7J */
  164.     if(if_asy->type != CL_AX25) {
  165.         tprintf("Multidrop KISS not allowed in interface: %s\n",argv[1]);
  166.         return -1;
  167.     }
  168.  
  169.     if(if_lookup(argv[3]) != NULLIF){
  170.         tprintf("Interface %s already exists\n",argv[4]);
  171.         return -1;
  172.     }
  173.  
  174.     if((port = atoi(argv[2])) == 0){
  175.         tprintf("Port 0 automatically assigned to interface %s\n",argv[1]);
  176.         return -1;
  177.     }
  178.  
  179.     if(port < 1 || port > 15){
  180.         tprintf("Ports 1 to 15 only\n");
  181.         return -1;
  182.     }
  183.  
  184.     if(Slip[if_asy->xdev].kiss[port] != NULLIF){
  185.         tprintf("Port %d already allocated on interface %s\n", port, argv[1]);
  186.         return -1;
  187.     }
  188.     /* Create interface structure and fill in details */
  189.     if_kiss = (struct iface *)callocw(1,sizeof(struct iface));
  190.     if_kiss->addr = if_asy->addr;
  191.     if_kiss->name = strdup(argv[3]);
  192.  
  193.     if(argc >= 5){
  194.         if_kiss->mtu = atoi(argv[4]);
  195.     } else {
  196.         if_kiss->mtu = if_asy->mtu;
  197.     }
  198.  
  199.     if_kiss->dev = if_asy->dev;
  200.     if_kiss->stop = kiss_stop;
  201.     setencap(if_kiss,"AX25");
  202.     if_kiss->ioctl = kiss_ioctl;
  203.     if_kiss->raw = kiss_raw;
  204.     if(if_kiss->hwaddr == NULLCHAR)
  205.         if_kiss->hwaddr = mallocw(AXALEN);
  206.     memcpy(if_kiss->hwaddr,Mycall,AXALEN);
  207.     if_kiss->xdev = if_asy->xdev;
  208.     if_kiss->next = Ifaces;
  209.     Ifaces = if_kiss;
  210.     if_kiss->port = port;
  211.     Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
  212.     return 0;
  213. }
  214.